# -*- coding: utf-8 -*-
from MySpi import *
import thosttraderapi as api
import configparser
import os
import sys
import time


#local config check check
if(os.path.exists("config.local.ini")):
	configfile = "config.local.ini"
else:
	configfile = "config.ini"

configins=configparser.ConfigParser()
configins.read(configfile)

#Addr
FrontAddr=configins['network']['tradefront']
#AuthInfo
APPID=configins['authinfo']['appid']
AUTHCODE=configins['authinfo']['authcode']
#LoginInfo
BROKERID=configins['baseinfo']['brokerid']
#OrderInfo
EXCHANGEID=configins['ordercon']['exid']
INSTRUMENTID=configins['ordercon']['instrid']
ORDERTYPE=configins['ordercon']['orprtype']
HEDGEFLAG=configins['ordercon']['hedgeflag']

VOLUME=int(configins['ordercon']['volumetotorg'])
MINVOL=int(configins['ordercon']['minvol'])
STOPPRICE=float(configins['ordercon']['stopprice'])
VOLUMECONDITION=configins['ordercon']['volumecon']
TIMECONDITION=configins['ordercon']['timecon']
CONTIGENCON=configins['ordercon']['contingencon']
#stressconfig
insertfreq = configins['stressconfig']['insertfreq']
cancelreq = float(configins['stressconfig']['cancelreq'])
oneturnsleep = float(insertfreq)
cancelorder = configins['stressconfig']['cancelorder']


class CTradeApi(api.CThostFtdcTraderApi):
	def __init__(self):
		self.tspi=''
		self.tapi=''
		self.invid=''
		self.passwd=''
		self.pricecatch={}
		self.instrcatch={}
		self.loginflag = False
		self.settleconfirm = False
		self.priceqry = False
		self.instrqry = False
		self.refcount=0
		self.ORDERREF=""
		self.refstr = ['BY', 'SE']
		self.frontid = ''
		self.sessionid = ''
		if(cancelorder == "1"):
			self.actionfunc = self.ReqOrInandDel
		else:
			self.actionfunc = self.ReqOrIn

		if(sys.platform == 'darwin'):
			self.loginfunc = self.ReqLoginMac
		else:
			self.loginfunc = self.ReqLoginGen

	def start(self, invid, passwd):
		self.invid = invid
		self.passwd= passwd
		#print("in start" + self.invid)
		self.tapi=api.CThostFtdcTraderApi.CreateFtdcTraderApi()
		self.tspi=CTradeSpi(self)
		self.tapi.RegisterFront(FrontAddr)
		#print(FrontAddr)
		self.tapi.RegisterSpi(self.tspi)
		self.tapi.SubscribePrivateTopic(api.THOST_TERT_QUICK)
		#self.tapi.SubscribePublicTopic(api.THOST_TERT_QUICK)
		self.tapi.SubscribePublicTopic(api.THOST_TERT_NONE)
		self.tapi.Init()
		#print("init end")

	def ReqAuth(self):
		authfield = api.CThostFtdcReqAuthenticateField()
		authfield.BrokerID=BROKERID
		authfield.UserID=self.invid
		authfield.AppID=APPID
		authfield.AuthCode=AUTHCODE
		self.tapi.ReqAuthenticate(authfield,0)
		PrintSendName("ReqAuthenticate")

	def ReqLoginGen(self):
		loginfield = api.CThostFtdcReqUserLoginField()
		loginfield.BrokerID=BROKERID
		loginfield.UserID=self.invid
		loginfield.Password=self.passwd
		loginfield.UserProductInfo="python dll"
		self.tapi.ReqUserLogin(loginfield,0)
		PrintSendName("ReqUserLogin")

	def ReqLoginMac(self):
		loginfield = api.CThostFtdcReqUserLoginField()
		loginfield.BrokerID=BROKERID
		loginfield.UserID=self.invid
		loginfield.Password=self.passwd
		loginfield.UserProductInfo="python dll"
		self.tapi.ReqUserLogin(loginfield,0,260,'')
		PrintSendName("ReqUserLogin")

	def ReqLogin(self):
		self.loginfunc()

	def ReqQrySettleInfo(self):
		qryinfofield = api.CThostFtdcQrySettlementInfoField()
		qryinfofield.BrokerID=self.BROKERID
		qryinfofield.InvestorID=self.invid
		self.tapi.ReqQrySettlementInfo(qryinfofield,0)
		PrintSendName("ReqQrySettlementInfo")

	def ReqSettleInfoConfirm(self):
		pSettlementInfoConfirm=api.CThostFtdcSettlementInfoConfirmField()
		pSettlementInfoConfirm.BrokerID=BROKERID
		pSettlementInfoConfirm.InvestorID=self.invid
		self.tapi.ReqSettlementInfoConfirm(pSettlementInfoConfirm,0)
		PrintSendName("ReqSettlementInfoConfirm")

	def OrderAction(self, instrid, price, dirt, offset):
		self.ORDERREF = str(self.refcount).zfill(7) + self.refstr[dirt]
		self.actionfunc(instrid, price, dirt, offset)
		self.refcount += 1

	def ReqOrIn(self, instrid, price, dirt, offset):
		pInOrder=api.CThostFtdcInputOrderField()
		pInOrder.BrokerID=BROKERID
		pInOrder.InvestorID=self.invid
		pInOrder.UserID=self.invid
		pInOrder.ExchangeID=EXCHANGEID
		pInOrder.InstrumentID=instrid
		pInOrder.OrderRef=self.ORDERREF
		pInOrder.Direction=str(dirt)
		pInOrder.LimitPrice=price
		pInOrder.VolumeTotalOriginal=VOLUME
		pInOrder.OrderPriceType=ORDERTYPE
		pInOrder.ContingentCondition=CONTIGENCON
		pInOrder.CombOffsetFlag=str(offset)
		pInOrder.CombHedgeFlag=HEDGEFLAG
		pInOrder.TimeCondition=TIMECONDITION
		pInOrder.VolumeCondition=VOLUMECONDITION
		pInOrder.MinVolume=MINVOL
		pInOrder.IsAutoSuspend=0
		pInOrder.StopPrice=STOPPRICE
		pInOrder.ForceCloseReason=api.THOST_FTDC_FCC_NotForceClose
		pInOrder.IsSwapOrder=0
		pInOrder.UserForceClose=0
		self.tapi.ReqOrderInsert(pInOrder, 0)
		PrintSendName("ReqOrderInsert")
	
	def ReqOrInandDel(self, instrid, price, dirt, offset):
		pInOrder=api.CThostFtdcInputOrderField()
		pInOrder.BrokerID=BROKERID
		pInOrder.InvestorID=self.invid
		pInOrder.UserID=self.invid
		pInOrder.ExchangeID=EXCHANGEID
		pInOrder.InstrumentID=instrid
		pInOrder.OrderRef=self.ORDERREF
		pInOrder.Direction=str(dirt)
		pInOrder.LimitPrice=price
		pInOrder.VolumeTotalOriginal=VOLUME
		pInOrder.OrderPriceType=ORDERTYPE
		pInOrder.ContingentCondition=CONTIGENCON
		pInOrder.CombOffsetFlag=str(offset)
		pInOrder.CombHedgeFlag=HEDGEFLAG
		pInOrder.TimeCondition=TIMECONDITION
		pInOrder.VolumeCondition=VOLUMECONDITION
		pInOrder.MinVolume=MINVOL
		pInOrder.IsAutoSuspend=0
		pInOrder.StopPrice=STOPPRICE
		pInOrder.ForceCloseReason=api.THOST_FTDC_FCC_NotForceClose
		pInOrder.IsSwapOrder=0
		pInOrder.UserForceClose=0
		self.tapi.ReqOrderInsert(pInOrder, 0)
		PrintSendName("ReqOrderInsert")
		time.sleep(cancelreq)
		pInOrderAction = api.CThostFtdcInputOrderActionField()
		pInOrderAction.BrokerID = BROKERID
		pInOrderAction.InvestorID = self.invid
		pInOrderAction.OrderRef = self.ORDERREF
		pInOrderAction.ExchangeID = EXCHANGEID
		pInOrderAction.UserID = self.invid
		pInOrderAction.InstrumentID = instrid
		pInOrderAction.FrontID = self.frontid
		pInOrderAction.SessionID = self.sessionid
		pInOrderAction.ActionFlag = api.THOST_FTDC_AF_Delete
		self.tapi.ReqOrderAction(pInOrderAction, 0)
		PrintSendName("ReqOrderdel")
	
	def ReqQryMD(self):
		self.pricecatch.clear()
		mdfield = api.CThostFtdcQryDepthMarketDataField()
		self.tapi.ReqQryDepthMarketData(mdfield, 0)
		PrintSendName("ReqQryDepthMarketData")

	def ReqQryInstr(self):
		self.instrcatch.clear()
		instrfield = api.CThostFtdcQryInstrumentField()
		instrfield.ExchangeID = EXCHANGEID
		self.tapi.ReqQryInstrument(instrfield, 0)
		PrintSendName("ReqQryInstrument")

	def LoginCheck(self):
		return self.loginflag

	def SettConfirmCheck(self):
		return self.settleconfirm
	
	def PriceQryCheck(self):
		return self.priceqry

	def InstrQryCheck(self):
		return self.instrqry

	def GetPriceQry(self):
		return self.pricecatch

	def GetInstrQry(self):
		return self.instrcatch

def PrintSendName(sendname):
	print("send", sendname, "ok")
